package com.aispeech.task.etcd;

import com.aispeech.task.common.utils.HttpUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.StringUtils;

import java.util.Iterator;
import java.util.Properties;

public class EtcdConfigClient {
    public static Properties loadEtcdConfig(String etcdServerLists) throws JsonProcessingException {
        if (StringUtils.isNoneBlank(etcdServerLists)) {
            System.out.println("[ EtcdConfigClient ] The etcdServerLists: " + etcdServerLists);
            String leader = getEtcdLeader(etcdServerLists);
            System.out.println("[ EtcdConfigClient ] The etcd leader is: " + leader);

            return StringUtils.isBlank(leader) ? null : loadConfigfFromLeader(leader);
        } else {
            System.err.println("[ EtcdConfigClient ] The etcdServerLists is empty!");
            return null;
        }
    }

    private static Properties loadConfigfFromLeader(String leader) throws JsonProcessingException {
        String projectIndentification = System.getProperty("ETCD_PROJECT_IDENTIFICATION");
//        String projectIndentification = System.getenv("ETCD_PROJECT_IDENTIFICATION");

        Properties properties = null;
        if (StringUtils.isNoneBlank(projectIndentification)) {
            System.out.println("[ EtcdConfigClient ] The current project is " + projectIndentification);

            String message = HttpUtils.get(String.format("%s/v2/keys/%s??recursive=true&sorted=true",
                    leader, projectIndentification));

            properties = parseEtcdConfig(projectIndentification, message);
        } else {
            System.out.println("[ EtcdConfigClient ] No project identification is configured in Dockerfile.");
            throw new RuntimeException("No project identification is configured in Dockerfile.");
        }

        return properties;
    }

    private static Properties parseEtcdConfig(String indentification, String message) throws JsonProcessingException {
        Properties properties = null;
        int index = indentification.length();

        if (StringUtils.isNoneBlank(message)) {
            ObjectMapper objectMapper = new ObjectMapper();
            JsonNode json = objectMapper.readTree(message);
            JsonNode jsonNodes = json.get("node").get("nodes");

            if (jsonNodes != null && jsonNodes.size() > 0) {
                properties = new Properties();

                for (int i = 0; i < jsonNodes.size(); i++) {
                    JsonNode item = jsonNodes.get(i);

                    String key = item.get("key").asText().substring(index + 2);
                    String value = item.get("value").asText();

                    properties.setProperty(key, value);
                }
            }
        }

        return properties;
    }

    private static String getEtcdLeader(String etcdServerLists) throws JsonProcessingException {
        String filted = etcdServerLists
                .replace("\"", "")
                .replace("'", "")
                .replace("[", "")
                .replace("]", "");

        if (StringUtils.isNoneBlank(filted)) {
            String[] arrServerList = filted.split(",");

            for (int i = 0; i < arrServerList.length; i++) {
                String node = arrServerList[i];
                String result = HttpUtils.get(node + "/v2/stats/leader");

                if (isMaster(result))
                    return node;
            }
        }

        return null;
    }

    private static boolean isMaster(String result) throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();

        JsonNode node = mapper.readTree(result);
        String leader = node.get("leader").asText();

        return StringUtils.isNoneBlank(leader);
    }

    public static void main(String[] args) throws JsonProcessingException {
        System.setProperty("ETCD_PROJECT_IDENTIFICATION", "cdc/cdc-web-mgr");

        String etcdServerLists = "[\"http://10.12.6.35:2379\"]";
        Properties properties = EtcdConfigClient.loadEtcdConfig(etcdServerLists);

        if (properties != null && properties.size() > 0) {
            properties.forEach((key, value) -> {
                System.out.println(String.format("[ prop ] %s ===> %s", key, value));
            });
        } else {
            System.err.println(String.format("[ prop ] %s", properties));
        }
    }
}
